API Reference
This page collects the public Tensorial API. Use the manual pages for examples and workflows, and use this page to look up signatures and detailed behavior.
- Constructors and special tensors
- Symmetry API
- Core operations
- Continuum mechanics API
- Rotations and quaternions
- Spectral functions
- Automatic differentiation API
- Direct sum API
- Voigt and Mandel API
Tensor types
Tensorial values are statically sized AbstractArrays whose type records the tensor space.
Tensor{S, T, N, L}is the general tensor type.Vec{dim, T}andMat{m, n, T, L}are vector and matrix aliases.SecondOrderTensor{dim, T, L}andFourthOrderTensor{dim, T, L}are square tensor aliases.SymmetricSecondOrderTensor{dim, T, L}andSymmetricFourthOrderTensor{dim, T, L}use symmetric tensor spaces.
See Tensor Types and Spaces and Constructing Tensors for examples.
Tensorial.Tensor — Type
Tensor{S, T, N, L}Statically sized tensor with tensor space S, element type T, tensor order N, and L stored independent components.
The tensor space S is a tuple of ordinary dimensions and symmetry groups. For example, Tensor{Tuple{3,3}} is a general 3×3 second-order tensor, while Tensor{Tuple{@Symmetry{3,3}}} is a symmetric 3×3 second-order tensor.
Tensorial.Vec — Type
Vec{dim, T}Alias for a first-order tensor with dim components.
Tensorial.Mat — Type
Mat{m, n, T, L}Alias for an m×n second-order tensor.
Tensorial.SecondOrderTensor — Type
SecondOrderTensor{dim, T, L}Alias for a general second-order tensor in dim dimensions.
Tensorial.FourthOrderTensor — Type
FourthOrderTensor{dim, T, L}Alias for a general fourth-order tensor in dim dimensions.
Tensorial.SymmetricSecondOrderTensor — Type
SymmetricSecondOrderTensor{dim, T, L}Alias for a symmetric second-order tensor in dim dimensions.
Tensorial.SymmetricFourthOrderTensor — Type
SymmetricFourthOrderTensor{dim, T, L}Alias for a fourth-order tensor whose first two and last two indices are symmetric.
Constructors and special tensors
Tensorial.@Vec — Macro
@Vec [a, b, c, d]
@Vec [i for i in 1:2]
@Vec ones(2)A convenient macro to construct Vec.
Tensorial.@Mat — Macro
@Mat [a b c d]
@Mat [[a, b];[c, d]]
@Mat [i+j for i in 1:2, j in 1:2]
@Mat ones(2, 2)A convenient macro to construct Mat.
Tensorial.@Tensor — Macro
@Tensor [a b; c d]
@Tensor [[a, b];[c, d]]
@Tensor [i+j for i in 1:2, j in 1:2]
@Tensor ones(2, 2, 2)A convenient macro to construct Tensor with arbitrary dimension.
Base.one — Function
one(TensorType)Return the identity tensor associated with the tensor space represented by TensorType.
The identity tensor is defined as the linear operator that leaves a tensor unchanged under contraction. It exists only for even-order tensors whose first and second halves span the same space. For symmetric spaces, component multiplicities are accounted for accordingly.
Examples
julia> I = one(Tensor{Tuple{@Symmetry{2, 2}, @Symmetry{2, 2}}});
julia> A = rand(Tensor{Tuple{@Symmetry{2, 2}}})
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
0.325977 0.549051
0.549051 0.218587
julia> I ⊡₂ A
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
0.325977 0.549051
0.549051 0.218587Tensorial.levicivita — Function
levicivita(::Val{N} = Val(3))Return N dimensional Levi-Civita tensor.
Examples
julia> ϵ = levicivita()
3×3×3 Tensor{Tuple{3, 3, 3}, Int64, 3, 27}:
[:, :, 1] =
0 0 0
0 0 1
0 -1 0
[:, :, 2] =
0 0 -1
0 0 0
1 0 0
[:, :, 3] =
0 1 0
-1 0 0
0 0 0Symmetry API
Tensorial.Symmetry — Type
Symmetry{S}
Symmetry(dims...)Symmetric index group used in tensor spaces.
All dimensions in one symmetry group must be equal. In type-level tensor spaces, the usual spelling is @Symmetry.
Examples
julia> Symmetry(3, 3)
Symmetry(3, 3)Tensorial.@Symmetry — Macro
@Symmetry{dim, dim, ...}Type-level spelling for a symmetric index group.
Use it inside Tensor{Tuple{...}} when several neighboring tensor indices are symmetric.
Examples
julia> S = rand(Tensor{Tuple{@Symmetry{3,3}}});
julia> S isa SymmetricSecondOrderTensor{3}
trueTensorial.symmetric — Function
symmetric(::AbstractSecondOrderTensor)
symmetric(::AbstractSecondOrderTensor, uplo)Compute the symmetric part of a second order tensor.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> symmetric(x)
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.721648 0.585856
0.721648 0.353112 0.594901
0.585856 0.594901 0.49425
julia> symmetric(x, :U)
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.894245 0.953125
0.894245 0.353112 0.795547
0.953125 0.795547 0.49425Tensorial.skew — Function
skew(A)Compute skew-symmetric (anti-symmetric) part of a second order tensor.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> symmetric(x) + skew(x) ≈ x
trueskew(ω::Vec{3})Construct a skew-symmetric (anti-symmetric) tensor W from a vector ω as
\[\bm{\omega} = \begin{Bmatrix} \omega_1 \\ \omega_2 \\ \omega_3 \end{Bmatrix}, \quad \bm{W} = \begin{bmatrix} 0 & -\omega_3 & \omega_2 \\ \omega_3 & 0 & -\omega_1 \\ -\omega_2 & \omega_1 & 0 \end{bmatrix}\]
Examples
julia> skew(Vec(1,2,3))
3×3 Tensor{Tuple{3, 3}, Int64, 2, 9}:
0 -3 2
3 0 -1
-2 1 0Tensorial.minorsymmetric — Function
minorsymmetric(::AbstractFourthOrderTensor) -> SymmetricFourthOrderTensorCompute the minor symmetric part of a fourth order tensor.
Examples
julia> x = rand(Tensor{Tuple{3,3,3,3}});
julia> minorsymmetric(x) ≈ @einsum (i,j,k,l) -> (x[i,j,k,l] + x[j,i,k,l] + x[i,j,l,k] + x[j,i,l,k]) / 4
trueCore operations
LinearAlgebra.cross — Function
cross(x::Vec, y::Vec)
x × yCompute the cross product between two vectors. The infix operation x × y (where × can be typed by \times<tab>) is a synonym for cross(x, y).
Examples
julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> y = rand(Vec{3})
3-element Vec{3, Float64}:
0.8942454282009883
0.35311164439921205
0.39425536741585077
julia> x × y
3-element Vec{3, Float64}:
0.13928086435138393
0.0669520417303531
-0.37588028973385323LinearAlgebra.norm — Function
norm(::AbstractTensor)Compute norm of a tensor.
Examples
julia> x = rand(Mat{3, 3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> norm(x)
1.8223398556552728LinearAlgebra.normalize — Function
normalize(x)Compute x / norm(x).
LinearAlgebra.tr — Function
tr(A)Compute the trace of a square tensor A.
Examples
julia> A = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> tr(A)
1.1733382401532275Base.inv — Function
inv(A)Return the inverse of A.
Tensorial treats an even-order tensor as a linear operator: the second half of the indices is the input space, and the first half is the output space. inv(A) is defined when those two spaces match and A stores a full n × n operator on that space, where n is the number of independent components. For symmetric tensor spaces, component multiplicities are accounted for in this operator representation.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> inv(x) * x ≈ one(x)
true
julia> A = rand(SymmetricFourthOrderTensor{3});
julia> A ⊡₂ inv(A) ≈ one(A)
trueTensorial.contract — Function
contract(x, y, ::Val{N})Conduct contraction of N inner indices. For example, N=2 contraction for third-order tensors $A_{ij} = B_{ikl} C_{klj}$ can be computed as follows:
Examples
julia> B = rand(Tensor{Tuple{3,3,3}});
julia> C = rand(Tensor{Tuple{3,3,3}});
julia> A = contract(B, C, Val(2))
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
3.70978 2.47156 3.91807
2.90966 2.30881 3.25965
1.78391 1.38714 2.2079The following infix operators are also available for specific contractions:
x ⊡ y(where⊡can be typed by\boxdot<tab>):contract(x, y, Val(1))x ⊡₂ y(where⊡₂can be typed by\boxdot<tab>\_2<tab>):contract(x, y, Val(2))x ⊗ y(where⊗can be typed by\otimes<tab>):contract(x, y, Val(0))
contract(x, y, Val(xdims), Val(ydims))Perform contraction over the given dimensions.
Examples
julia> A = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> B = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.748415 0.00744801 0.682533
0.578232 0.199377 0.956741
0.727935 0.439243 0.647855
julia> contract(A, B, Val(1), Val(2)) ≈ @einsum A[k,i] * B[j,k]
true
julia> contract(A, B, Val((1,2)), Val((2,1))) ≈ @einsum A[i,j] * B[j,i]
trueTensorCore.tensor — Function
tensor(x::AbstractTensor, y::AbstractTensor)
x ⊗ yCompute tensor product such as $A_{ij} = x_i y_j$. x ⊗ y (where ⊗ can be typed by \otimes<tab>) is a synonym for tensor(x, y).
Examples
julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> y = rand(Vec{3})
3-element Vec{3, Float64}:
0.8942454282009883
0.35311164439921205
0.39425536741585077
julia> A = x ⊗ y
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.291503 0.115106 0.128518
0.490986 0.193876 0.216466
0.19547 0.0771855 0.086179Base.:^ — Function
x^⊗(n)n-fold tensor product of a tensor x.
Examples
julia> x = rand(Vec{2})
2-element Vec{2, Float64}:
0.32597672886359486
0.5490511363155669
julia> x^⊗(3)
2×2×2 Tensor{Tuple{Symmetry{Tuple{2, 2, 2}}}, Float64, 3, 4}:
[:, :, 1] =
0.0346386 0.0583426
0.0583426 0.098268
[:, :, 2] =
0.0583426 0.098268
0.098268 0.165515Tensorial.@einsum — Macro
@einsum [TensorType] exprPerforms tensor computations using the Einstein summation convention. Since @einsum cannot fully infer tensor symmetries, it is possible to annotate the returned tensor type (though this is not checked for correctness). This can help eliminate the computation of the symmetric part, improving performance.
The expr can be an anonymous function, in which case the arguments of the anonymous function are treated as free indices. If no arguments are provided, the free indices are inferred based on the order in which they appear from left to right.
Examples
julia> A = rand(Mat{3,3});
julia> B = rand(Mat{3,3});
julia> (@einsum C[i,j] := A[j,k] * B[k,i]) ≈ (A * B)'
true
julia> (@einsum c := A[i,j] * A[i,j]) ≈ A ⋅ A
true
julia> (@einsum SymmetricSecondOrderTensor{3} D[i,j] := A[k,i] * A[k,j]) ≈ A' * A
true
julia> (@einsum (i,j) -> A[j,k] * B[k,i]) ≈ (A * B)'
true
julia> (@einsum A[i,j] * A[i,j]) ≈ A ⋅ A
true
julia> (@einsum SymmetricSecondOrderTensor{3} A[k,i] * A[k,j]) ≈ A' * A
trueContinuum mechanics API
Tensorial.vol — Function
vol(A)Compute the volumetric part of a square tensor A. This is only available in 3D.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> vol(x)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.391113 0.0 0.0
0.0 0.391113 0.0
0.0 0.0 0.391113
julia> vol(x) + dev(x) ≈ x
truevol(::AbstractVec{3})Compute the volumetric part of a vector (assuming principal values of stresses and strains). This is only available in 3D.
Examples
julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> vol(x)
3-element Vec{3, Float64}:
0.3645381733326641
0.3645381733326641
0.3645381733326641
julia> vol(x) + dev(x) ≈ x
truevol(::Type{FourthOrderTensor{3}})
vol(::Type{SymmetricFourthOrderTensor{3}})Construct volumetric fourth order identity tensor. This is only available in 3D.
Examples
julia> x = rand(Mat{3,3});
julia> I_vol = vol(FourthOrderTensor{3});
julia> I_vol ⊡₂ x ≈ vol(x)
true
julia> vol(FourthOrderTensor{3}) + dev(FourthOrderTensor{3}) ≈ one(FourthOrderTensor{3})
trueTensorial.dev — Function
dev(::AbstractSecondOrderTensor{3})
dev(::AbstractSymmetricSecondOrderTensor{3})Compute the deviatoric part of a square tensor. This is only available in 3D.
Examples
julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.325977 0.894245 0.953125
0.549051 0.353112 0.795547
0.218587 0.394255 0.49425
julia> dev(x)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
-0.065136 0.894245 0.953125
0.549051 -0.0380011 0.795547
0.218587 0.394255 0.103137
julia> tr(dev(x))
5.551115123125783e-17dev(::AbstractVec{3})Compute the deviatoric part of a vector (assuming principal values of stresses and strains). This is only available in 3D.
Examples
julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> dev(x)
3-element Vec{3, Float64}:
-0.03856144446906923
0.18451296298290282
-0.14595151851383342
julia> vol(x) + dev(x) ≈ x
truedev(::Type{FourthOrderTensor{3}})
dev(::Type{SymmetricFourthOrderTensor{3}})Construct deviatoric fourth order identity tensor. This is only available in 3D.
Examples
julia> x = rand(Mat{3,3});
julia> I_dev = dev(FourthOrderTensor{3});
julia> I_dev ⊡₂ x ≈ dev(x)
true
julia> vol(FourthOrderTensor{3}) + dev(FourthOrderTensor{3}) ≈ one(FourthOrderTensor{3})
trueTensorial.vonmises — Function
vonmises(::AbstractSymmetricSecondOrderTensor{3})Compute the von Mises stress.
\[q = \sqrt{\frac{3}{2} \mathrm{dev}(\bm{\sigma}) : \mathrm{dev}(\bm{\sigma})} = \sqrt{3J_2}\]
Examples
julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> vonmises(σ)
1.3078860814690232Tensorial.stress_invariants — Function
stress_invariants(::AbstractSecondOrderTensor{3})
stress_invariants(::AbstractSymmetricSecondOrderTensor{3})
stress_invariants(::Vec{3})Return a tuple storing stress invariants.
\[\begin{aligned} I_1(\bm{\sigma}) &= \mathrm{tr}(\bm{\sigma}) \\ I_2(\bm{\sigma}) &= \frac{1}{2} (\mathrm{tr}(\bm{\sigma})^2 - \mathrm{tr}(\bm{\sigma}^2)) \\ I_3(\bm{\sigma}) &= \det(\bm{\sigma}) \end{aligned}\]
Examples
julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> I₁, I₂, I₃ = stress_invariants(σ)
(1.6144775244804341, 0.2986572249840249, -0.0025393241133506677)Tensorial.deviatoric_stress_invariants — Function
deviatoric_stress_invariants(::AbstractSecondOrderTensor{3})
deviatoric_stress_invariants(::AbstractSymmetricSecondOrderTensor{3})
deviatoric_stress_invariants(::Vec{3})Return a tuple storing deviatoric stress invariants.
\[\begin{aligned} J_1(\bm{\sigma}) &= \mathrm{tr}(\mathrm{dev}(\bm{\sigma})) = 0 \\ J_2(\bm{\sigma}) &= \frac{1}{2} \mathrm{tr}(\mathrm{dev}(\bm{\sigma})^2) \\ J_3(\bm{\sigma}) &= \frac{1}{3} \mathrm{tr}(\mathrm{dev}(\bm{\sigma})^3) \end{aligned}\]
Examples
julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> J₁, J₂, J₃ = deviatoric_stress_invariants(σ)
(0.0, 0.5701886673667987, 0.14845380911930367)Rotations and quaternions
Tensorial.rotmatx — Function
rotmatx(θ::Number)Construct rotation matrix around x axis.
\[\bm{R}_x = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos{\theta} & -\sin{\theta} \\ 0 & \sin{\theta} & \cos{\theta} \end{bmatrix}\]
Tensorial.rotmaty — Function
rotmaty(θ::Number)Construct rotation matrix around y axis.
\[\bm{R}_y = \begin{bmatrix} \cos{\theta} & 0 & \sin{\theta} \\ 0 & 1 & 0 \\ -\sin{\theta} & 0 & \cos{\theta} \end{bmatrix}\]
Tensorial.rotmatz — Function
rotmatz(θ::Number)Construct rotation matrix around z axis.
\[\bm{R}_z = \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0 \\ \sin{\theta} & \cos{\theta} & 0 \\ 0 & 0 & 1 \end{bmatrix}\]
Tensorial.rotmat — Function
rotmat(θ::Number)Construct 2D rotation matrix.
\[\bm{R} = \begin{bmatrix} \cos{\theta} & -\sin{\theta} \\ \sin{\theta} & \cos{\theta} \end{bmatrix}\]
Examples
julia> rotmat(deg2rad(30))
2×2 Tensor{Tuple{2, 2}, Float64, 2, 4}:
0.866025 -0.5
0.5 0.866025rotmat(θ::Vec{3}; sequence::Symbol)Convert Euler angles to rotation matrix. Use 3 characters belonging to the set (X, Y, Z) for intrinsic rotations, or (x, y, z) for extrinsic rotations.
Examples
julia> α, β, γ = map(deg2rad, rand(3));
julia> rotmat(Vec(α,β,γ), sequence = :XYZ) ≈ rotmatx(α) * rotmaty(β) * rotmatz(γ)
true
julia> rotmat(Vec(α,β,γ), sequence = :xyz) ≈ rotmatz(γ) * rotmaty(β) * rotmatx(α)
true
julia> rotmat(Vec(α,β,γ), sequence = :XYZ) ≈ rotmat(Vec(γ,β,α), sequence = :zyx)
truerotmat(θ, n::Vec)Construct rotation matrix from angle θ and axis n. n must be a unit vector.
Examples
julia> x = Vec(1.0, 0.0, 0.0)
3-element Vec{3, Float64}:
1.0
0.0
0.0
julia> n = Vec(0.0, 0.0, 1.0)
3-element Vec{3, Float64}:
0.0
0.0
1.0
julia> rotmat(π/2, n) * x
3-element Vec{3, Float64}:
6.123233995736766e-17
1.0
0.0rotmat(::Quaternion)Construct rotation matrix from quaternion.
Examples
julia> q = quaternion(π/4, Vec(0,0,1))
0.9238795325112867 + 0.0𝙞 + 0.0𝙟 + 0.3826834323650898𝙠
julia> rotmat(q)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.707107 -0.707107 0.0
0.707107 0.707107 0.0
0.0 0.0 1.0Tensorial.rotate — Function
rotate(x, R::SecondOrderTensor)Rotate x using the rotation matrix R. Supported inputs are vectors and second- and fourth-order tensors; symmetric tensor types are rotated into the corresponding symmetric tensor type.
Examples
julia> R = rotmatz(π/4)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
0.707107 -0.707107 0.0
0.707107 0.707107 0.0
0.0 0.0 1.0
julia> rotate(Vec(1,0,0), R)
3-element Vec{3, Float64}:
0.7071067811865476
0.7071067811865475
0.0
julia> A = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
0.325977 0.549051 0.218587
0.549051 0.894245 0.353112
0.218587 0.353112 0.394255
julia> rotate(A, R) ≈ R * A * R'
truerotate(x::Vec, q::Quaternion)Rotate x by quaternion q.
Examples
julia> v = Vec(1.0, 0.0, 0.0)
3-element Vec{3, Float64}:
1.0
0.0
0.0
julia> rotate(v, quaternion(π/4, Vec(0,0,1)))
3-element Vec{3, Float64}:
0.7071067811865475
0.7071067811865476
0.0Tensorial.angleaxis — Function
angleaxis(R::SecondOrderTensor{3})Convert a 3D rotation matrix to an angle-axis pair (θ, n). R is assumed to be a rotation matrix; orthogonality and determinant are not validated.
angleaxis(::Quaternion)Convert a quaternion to an angle-axis pair (θ, n).
Tensorial.Quaternion — Type
Quaternion represents $q_w + q_x \bm{i} + q_y \bm{j} + q_z \bm{k}$. The scalar part and vector part can be accessed by q.scalar and q.vector, respectively.
Examples
julia> Quaternion(1,2,3,4)
1 + 2𝙞 + 3𝙟 + 4𝙠
julia> Quaternion(1)
1 + 0𝙞 + 0𝙟 + 0𝙠
julia> Quaternion(Vec(1,2,3))
0 + 1𝙞 + 2𝙟 + 3𝙠See also quaternion.
Tensorial.quaternion — Function
quaternion(θ, n::Vec)Construct Quaternion from angle θ and axis n as
\[q = \cos\frac{\theta}{2} + \bm{n} \sin\frac{\theta}{2}\]
n must be a unit vector.
Examples
julia> q = quaternion(π/4, Vec(0,0,1))
0.9238795325112867 + 0.0𝙞 + 0.0𝙟 + 0.3826834323650898𝙠
julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
0.32597672886359486
0.5490511363155669
0.21858665481883066
julia> (q * x / q).vector ≈ rotmatz(π/4) * x
trueSpectral functions
Base.sqrt — Method
sqrt(A::AbstractSymmetricSecondOrderTensor)Compute the principal square root of a symmetric second-order tensor.
For an eigendecomposition,
\[\bm{A} = \bm{Q} \operatorname{diag}(\lambda_i) \bm{Q}^\mathsf{T}, \quad \sqrt{\bm{A}} = \bm{Q} \operatorname{diag}(\sqrt{\lambda_i}) \bm{Q}^\mathsf{T}.\]
The result is a SymmetricSecondOrderTensor. Automatic differentiation is defined as a spectral tensor function, including repeated eigenvalues.
Base.exp — Method
exp(A::AbstractSymmetricSecondOrderTensor)Compute the exponential of a symmetric second-order tensor.
For an eigendecomposition,
\[\bm{A} = \bm{Q} \operatorname{diag}(\lambda_i) \bm{Q}^\mathsf{T}, \quad \exp(\bm{A}) = \bm{Q} \operatorname{diag}(\exp(\lambda_i)) \bm{Q}^\mathsf{T}.\]
The result is a SymmetricSecondOrderTensor. Automatic differentiation is defined as a spectral tensor function, including repeated eigenvalues.
Base.log — Method
log(A::AbstractSymmetricSecondOrderTensor)Compute the principal logarithm of a symmetric second-order tensor.
For an eigendecomposition,
\[\bm{A} = \bm{Q} \operatorname{diag}(\lambda_i) \bm{Q}^\mathsf{T}, \quad \log(\bm{A}) = \bm{Q} \operatorname{diag}(\log(\lambda_i)) \bm{Q}^\mathsf{T}.\]
The result is a SymmetricSecondOrderTensor. Automatic differentiation is defined as a spectral tensor function, including repeated eigenvalues.
Automatic differentiation API
Tensorial.gradient — Type
const gradient = ∂{1}Tensorial.hessian — Type
const hessian = ∂{2}Tensorial.∂ — Type
∂{N}An operator representing the Nth-order partial derivative.
∂{N} is callable. Applying it to a function f and its arguments computes Nth-order partial derivatives of f by automatic differentiation. ∂(f, args...) is equivalent to ∂{1}(f, args...).
If pseudo keyword :all is given as the last argument, derivatives of all orders up to N are returned together with the function value. For example, ∂{N}(f, x, :all) returns (∂{N}(f,x), ..., ∂{2}(f,x), ∂{1}(f,x), f(x)).
Direct sum API
Tensorial.DirectSumArray — Type
DirectSumArray{Axes, T, N, L}Container for an element of a direct-sum space stored in Mandel-flat coordinates.
Type parameters
Axes: block-space layout along each axisT: scalar storage typeN: block-array dimensionL: total number of flat stored entries
Notes
size(A)returns the block size.flatsize(A)returns the size of the flat Mandel storage.
Tensorial.DirectSumVector — Type
DirectSumVector{Axis1, T, L}One-dimensional DirectSumArray.
Tensorial.DirectSumMatrix — Type
DirectSumMatrix{Axis1, Axis2, T, L}Two-dimensional DirectSumArray.
Tensorial.pack — Function
pack(args...)Construct a DirectSumArray from the blocks of a direct-sum space.
Each argument is interpreted as one block of the direct sum. Scalar blocks are stored directly. Tensor blocks are flattened and concatenated into the internal storage. If a block belongs to a symmetric tensor space, Mandel coordinates are used internally.
⊕ (typed by \oplus<tab> ) is provided as an alias for pack.
Examples
julia> A = @Mat [1.0 2.0; 3.0 4.0]
2×2 Tensor{Tuple{2, 2}, Float64, 2, 4}:
1.0 2.0
3.0 4.0
julia> x = pack(A, 3.0)
2-element DirectSumVector with storage Float64:
Space(2, 2)
Space()
julia> As = symmetric(A)
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
1.0 2.5
2.5 4.0
julia> v = @Vec [4.0, 5.0]
2-element Vec{2, Float64}:
4.0
5.0
julia> y = As ⊕ 3.0 ⊕ v
3-element DirectSumVector with storage Float64:
Space(Symmetry(2, 2),)
Space()
Space(2,)Tensorial.unpack — Function
unpack(A::DirectSumArray)Return the blocks stored in a DirectSumArray.
unpack(A) returns all direct-sum blocks as a tuple. unpack(A, I...) returns the block at block index I. Tensor blocks are reconstructed from the internal flat storage. For symmetric tensor blocks, the internally stored Mandel coordinates are converted back to the corresponding tensor values.
At the level of block values, unpack is the inverse of pack.
unpack(A) is type-stable, but unpack(A, I...) may be type-unstable if the block index is not known at compile time, since different block indices may correspond to different return types. It is therefore most suitable when I is a constant and constant propagation can resolve the selected block.
Examples
julia> A = symmetric(@Mat [1.0 2.0; 3.0 4.0])
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
1.0 2.5
2.5 4.0
julia> x = pack(A, 3.0)
2-element DirectSumVector with storage Float64:
Space(Symmetry(2, 2),)
Space()
julia> unpack(x)
([1.0 2.5; 2.5 4.0], 3.0)
julia> unpack(x, 1)
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
1.0 2.5
2.5 4.0
julia> unpack(x, 2)
3.0Tensorial.flatview — Function
flatview(A::DirectSumArray)Return A as a flat coordinate array. Symmetric tensor blocks are represented in Mandel coordinates.
Examples
julia> A = @Mat [1.0 2.0; 3.0 4.0]
2×2 Tensor{Tuple{2, 2}, Float64, 2, 4}:
1.0 2.0
3.0 4.0
julia> x = pack(A, 3.0)
2-element DirectSumVector with storage Float64:
Space(2, 2)
Space()
julia> flatview(x)
5-element StaticArraysCore.SVector{5, Float64} with indices SOneTo(5):
1.0
3.0
2.0
4.0
3.0
julia> As = symmetric(A)
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
1.0 2.5
2.5 4.0
julia> y = pack(As, 3.0)
2-element DirectSumVector with storage Float64:
Space(Symmetry(2, 2),)
Space()
julia> flatview(y)
4-element StaticArraysCore.SVector{4, Float64} with indices SOneTo(4):
1.0
3.5355339059327378
4.0
3.0Tensorial.flatsize — Function
flatsize(A::DirectSumArray)
flatsize(::Type{<:DirectSumArray})Return the size of the flat Mandel-coordinate storage.
This differs from size(A), which returns the block size.
Examples
julia> A = symmetric(@Mat [1.0 2.0; 2.0 4.0]);
julia> x = pack(A, 3.0);
julia> size(x)
(2,)
julia> flatsize(x)
(4,)Voigt and Mandel API
Tensorial.tovoigt — Function
tovoigt(A::Union{SecondOrderTensor, FourthOrderTensor}; [order])
tovoigt(A::Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor}; [order, offdiagonal])Convert a tensor to Voigt form.
Keyword arguments:
offdiagscale: Determines the scaling factor for the offdiagonal elements.order: A vector of cartesian indices (Tuple{Int, Int}) determining the Voigt order. The default order is[(1,1), (2,2), (3,3), (2,3), (1,3), (1,2), (3,2), (3,1), (2,1)]fordim=3.
See also fromvoigt.
Examples
julia> x = Mat{3,3}(1:9...)
3×3 Tensor{Tuple{3, 3}, Int64, 2, 9}:
1 4 7
2 5 8
3 6 9
julia> tovoigt(x)
9-element StaticArraysCore.SVector{9, Int64} with indices SOneTo(9):
1
5
9
8
7
4
6
3
2
julia> x = SymmetricSecondOrderTensor{3}(1:6...)
3×3 SymmetricSecondOrderTensor{3, Int64, 6}:
1 2 3
2 4 5
3 5 6
julia> tovoigt(x; offdiagscale = 2,
order = [(1,1), (2,2), (3,3), (1,2), (1,3), (2,3)])
6-element StaticArraysCore.SVector{6, Int64} with indices SOneTo(6):
1
4
6
4
6
10Tensorial.tomandel — Function
tomandel(A::Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor})Convert a tensor to Mandel form which is equivalent to tovoigt(A, offdiagscale = √2).
See also tovoigt.
Tensorial.fromvoigt — Function
fromvoigt(S::Type{<: Union{SecondOrderTensor, FourthOrderTensor}}, A::AbstractArray{T}; [order])
fromvoigt(S::Type{<: Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor}}, A::AbstractArray{T}; [order, offdiagscale])Converts an array A stored in Voigt format to a Tensor of type S.
Keyword arguments:
offdiagscale: Determines the scaling factor for the offdiagonal elements.order: A vector of cartesian indices (Tuple{Int, Int}) determining the Voigt order. The default order is[(1,1), (2,2), (3,3), (2,3), (1,3), (1,2), (3,2), (3,1), (2,1)]fordim=3.
Since offdiagscale is the scaling factor for the offdiagonal elements in Voigt form, they are multiplied by 1/offdiagscale in fromvoigt unlike tovoigt. Thus fromvoigt(tovoigt(x, offdiagscale = 2), offdiagscale = 2) returns original x.
See also tovoigt.
Examples
julia> fromvoigt(Mat{3,3}, 1.0:1.0:9.0)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
1.0 6.0 5.0
9.0 2.0 4.0
8.0 7.0 3.0
julia> fromvoigt(SymmetricSecondOrderTensor{3},
1.0:1.0:6.0,
offdiagscale = 2.0,
order = [(1,1), (2,2), (3,3), (1,2), (1,3), (2,3)])
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
1.0 2.0 2.5
2.0 2.0 3.0
2.5 3.0 3.0Tensorial.frommandel — Function
frommandel(S::Type{<: Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor}}, A::AbstractArray{T})Create a tensor of type S from Mandel form. This is equivalent to fromvoigt(S, A, offdiagscale = √2).
See also fromvoigt.